package com.hongdee.crm.task.service.impl;

import com.hongdee.annotation.MethodComment;
import com.hongdee.common.util.DateUtils;
import com.hongdee.crm.Constant;
import com.hongdee.crm.maintain.entity.TCrmCarMaintain;
import com.hongdee.crm.task.dao.IBcMaintainTypeTaskDao;
import com.hongdee.crm.task.dao.ITCrmCarMaintainMileTaskDao;
import com.hongdee.crm.task.dao.ITCrmCarMaintainTaskDao;
import com.hongdee.crm.task.service.ITCrmCarMaintainMileTaskService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.util.*;

import static com.hongdee.crm.Constant.DEF_MILE;

/**
 * 名  称: TCrmCarMaintainMileTaskServiceImpl
 * 类  型: class
 * 描  述: 首保任务类
 * 路  径: com.hongdee.crm.task.service.impl
 * 作  者: wangshuai
 * 日  期:2017/2/28 10:23
 */
@Component
public class TCrmCarMaintainMileTaskServiceImpl implements ITCrmCarMaintainMileTaskService {

    @Autowired
    private ITCrmCarMaintainTaskDao carMaintainTaskDao;
    @Autowired
    private IBcMaintainTypeTaskDao bcMaintainTypeTaskDao;
    @Autowired
    private ITCrmCarMaintainMileTaskDao crmCarMaintainMileTaskDao;

    private final int LIMIT = 1000;
    private final String SB = "首保";
    private final String EB = "二保";
    private final String DB = "定保";
    private final String[] MAINTAINTYPE = {SB, EB, DB};

    private Map<String, Object> typeMap = new HashMap<>();
    private final String DEFTYPE = "一般维修";

    /**
     * 根据车辆工单生成车辆相关的保养里程信息
     * sql查询规则：
     * 1、根据首保、二保、定保查询配置的维修项目
     * 2、工单表、工单维修项目表连接
     * 3、根据配置的维修项目，生成查询sql语句
     * 4、执行查询
     * 计算步骤：
     * 1、取出公司信息，并遍历公司信息
     * 2、根据公司信息取出保养配置的维修项目
     * 3、根据公司的保养配置信息生成sql
     * 4、根据sql查询
     * 5、遍历工单信息、生成保养信息
     * 1）、车辆首保情况下，直接里程数/（保养日期-质保日期）算出平均里程，同时根据5000/平均里程 判断出下次保养时间
     * 2）、车辆二保情况下，直接里程数/（保养日期-首保日期）算出本次平均里程，同时根据(本次平均里程+上次平均里程)/2 ，最后根据5000/平均判断出下次保养时间
     * 3）、车辆定保情况下，查询之已经有的保养情况，如果之前有保养记录，取出最后三次；本次里程数-最后一次里程数/（本次保养时间-上次保养时间）=本次平均里程，
     * 本次平均里程+取出的最后三次的平均保养里程/4 得出平均里程数，然后根据5000/平均里程 判断出下次保养时间
     * 4）、判断下一保养时间是否大于（本次保养时间+6个月）目标月，如大于则执行目标月时间，如小于则不变
     * 5）、判断一条工单保养信息是否已经存在车辆保养表内，如存在则跳出本次循环，如不存在则保存
     *
     * @throws Exception
     */
//    @Scheduled(cron="0 0 2 * * ? *")//每天2点执行
    @Override
    @MethodComment(name = "生成车辆保养工单")
    public Integer createCarMaintainMileQuartz() throws Exception {
        Integer counts = 0;
        //1、取出公司信息
        List<Map<String, Object>> companyLists = bcMaintainTypeTaskDao.findCompanyList();
        //2、遍历公司，根据公司信息取出保养类型
        for (Map<String, Object> companyMap : companyLists) {
            String companyId = String.valueOf(companyMap.get("company_id"));
            counts += this.createCarMaintainMileByCompanyQuqrtz(companyId);
        }
        //每天更新车辆保养工单之后，刷新车辆下次保养时间及保养里程
        this.updCarNextMaintainMileAndTmeQuartz();
        return counts;
    }

    @Override
    @MethodComment(name = "按公司生成保养工单")
    public Integer createCarMaintainMileByCompanyQuqrtz(String companyId) throws Exception {
        Integer counts = 0;
        //3、根据公司的保养类型生成sql
        List<Map<String, Object>> maintainTypeList = bcMaintainTypeTaskDao.findMaintainTypeByComIdList(companyId);

        //4、根据生成的sql查询数据
        int start = 0;
        for (String type : MAINTAINTYPE) {
            //取出保养里程 按保养时间算 最大的一条数据
//            Long lastMaintainTime=this.getLastMaintainTime(type,companyId);
            while (true) {
                List<Object> params = new ArrayList<>();
                String sqlStr = this.analyCompanyToSql(maintainTypeList, params, companyId, type);
                params.add(start);
                params.add(LIMIT);
                System.out.println("sql:" + sqlStr);
                System.out.println("params:" + params.toString());
                List<Map<String, Object>> maintainList = crmCarMaintainMileTaskDao.findMainTainList(sqlStr, params);
                //退出判断
                if (maintainList == null) {
                    start = 0;
                    break;
                } else {
                    List<TCrmCarMaintain> lists = new ArrayList<>();
                    for (Map<String, Object> map : maintainList) {
                        String worderId = String.valueOf(map.get("id"));
                        if (map.get("guarantee_start_date") == null && map.get("buy_date") == null) {
                            continue;
                        }
                        //判断工单是否已经生成保养里程信息
                        int nums = 0;//crmCarMaintainMileTaskDao.findWorderCounts(worderId);
                        if (nums <= 0) {
                            TCrmCarMaintain crmCarMaintain = createMaintainInfo(map, type);
                            if ("定保".equals(type)) {
                                this.crmCarMaintainMileTaskDao.saveOrUpdate(crmCarMaintain);
                            } else {
                                lists.add(crmCarMaintain);
                            }
                        }
                    }
                    if (lists.size() > 0) {
                        counts = lists.size();
                        //6、生成数据后，将数据保存至数据库
                        long start1 = System.currentTimeMillis();
                        //插入车辆保养信息
                        crmCarMaintainMileTaskDao.insertMaintailLists(lists);
                        //更新车辆下次保养信息
                        crmCarMaintainMileTaskDao.updCarNextMaintainLists(lists);
                        long end = System.currentTimeMillis();
                        System.out.println("运行时间：" + (end - start1) + "毫秒");//应该是end - start
                    }
                }
//                start++;
            }
        }
        return counts;
    }

    /**
     * 生成保养里程信息
     *
     * @param map
     * @param type
     * @return
     * @throws Exception
     */
    private TCrmCarMaintain createMaintainInfo(Map<String, Object> map, String type) throws Exception {
        TCrmCarMaintain maintain = new TCrmCarMaintain();
        maintain.setCompanyId(String.valueOf(map.get("company_id")));//公司ID
        maintain.setCarId(String.valueOf(map.get("carId")));//车辆ID
        maintain.setVin(String.valueOf(map.get("vin")));//车驾号
        maintain.setMaintainTime(Long.valueOf(String.valueOf(map.get("balance_date"))));//保养时间
        maintain.setMaintainType(type);//保养类型
        maintain.setWorderId(String.valueOf(map.get("id")));//工单ID
        maintain.setPlateNum(String.valueOf(map.get("plateNum")));
        maintain.setContactName(String.valueOf(map.get("owner_name")));
        if (map.get("owner_phone") != null) {
            maintain.setContactPhone(String.valueOf(map.get("owner_phone")));
        } else {
            if (map.get("owner_tel") != null) {
                maintain.setContactPhone(String.valueOf(map.get("owner_tel")));
            }
        }
        //设置平均里程及下次保养时间
        this.avgMileAndNextMaintainTime(map, type, maintain);
        //本次保养的里程数
        String runMile = maintain.getMaintainMile();
        //上次保养时间
        Long maintainTime = maintain.getMaintainTime();
        //平均保养里程
        String avgMile = maintain.getAvgMaintainMile();
        Float days = (maintain.getNextMaintainTime() - maintainTime) / (60 * 60 * 24 * 1000F);
        Float addMile = days * Float.valueOf(avgMile);
        Float sumMile = Float.valueOf(runMile) + addMile;
        maintain.setNextMaintainMile(String.valueOf(sumMile));
        return maintain;
    }

    /**
     * 判断车辆保养平均里程、下次保养时间并且设置本次的部里程
     *
     * @param map         保养工单信息
     * @param type        首保、二保、定保
     * @param carMaintain
     * @throws Exception
     */
    private void avgMileAndNextMaintainTime(Map<String, Object> map, String type, TCrmCarMaintain carMaintain) throws Exception {
        String mType = String.valueOf(map.get("wx_type"));
//        mType=mType.substring(1,mType.length());
        Float fRunMile = Float.valueOf(String.valueOf(map.get("run_mile")));
        Float runMile = fRunMile;
        Float avgMile = null;
        //质保开始时间

        Long guaranteeDate = 0l;
        if (map.get("guarantee_start_date") != null) {
            guaranteeDate = Long.valueOf(String.valueOf(map.get("guarantee_start_date")));
        } else {
            if (map.get("buy_date") != null) {
                guaranteeDate = Long.valueOf(String.valueOf(map.get("buy_date")));
            }
        }
        if (guaranteeDate == 0) {
            return;
        }
        if (mType.equals(SB)) {
            avgMile = this.maintainAvgMile(carMaintain.getMaintainTime(), guaranteeDate, runMile);
        } else if (mType.equals(EB)) {
            avgMile = maintainEbAvgMile(carMaintain, guaranteeDate, runMile);
        } else if (mType.equals(DB)) {//定保计算其保养平均里程
            avgMile = this.maintainDbAvgMile(carMaintain, guaranteeDate, runMile);
        }
        if (avgMile == null) {
            System.out.println("");
        }
        //判断下次保养时间是否为空，如果不为空则需要根据平均里程来计算 为空 说明为首保
        if (carMaintain.getNextMaintainTime() == null) {
            //如果平均里程为0 说明日平均里程为1公里以下，下次保养时间肯定要大于6个月，直接设定为6个月
            if (avgMile > 0) {
                //计算车主5000公里需要多少天
                Float dateDifference = DEF_MILE / avgMile;
                Float dateDifferenceHour = dateDifference * 24;
                //设置下一次保养时间
                carMaintain.setNextMaintainTime(DateUtils.addHourLongTime(carMaintain.getMaintainTime(), +dateDifferenceHour.intValue()));
            } else {
                carMaintain.setNextMaintainTime(DateUtils.addMonthLongTime(carMaintain.getMaintainTime(), +6));
                carMaintain.setNextMaintainMile(String.valueOf(fRunMile + Constant.DEF_MILE));
            }
        }
        //判断是否超过六个月期限
        Long sixMaintainTime = DateUtils.addMonthLongTime(carMaintain.getMaintainTime(), +6);
        if (carMaintain.getNextMaintainTime() > sixMaintainTime) {
            carMaintain.setNextMaintainTime(sixMaintainTime);
        }
        //设置平均里程
        carMaintain.setAvgMaintainMile(String.valueOf(avgMile));
        //设置本次总里程
        carMaintain.setMaintainMile(String.valueOf(runMile));
    }

    /**
     * 二保计算平均里程、下次保养时间
     *
     * @param carMaintain
     * @param guaranteeDate
     * @param runMile
     * @return
     * @throws Exception
     */
    private Float maintainEbAvgMile(TCrmCarMaintain carMaintain, long guaranteeDate, Float runMile) throws Exception {
        float avgMile = 0F;
        //当前的平均里程+首保的平均里程/2
        //首保相关信息
        Map<String, Object> firstMantain = crmCarMaintainMileTaskDao.findLastMainTainInfo(carMaintain.getCompanyId(), carMaintain.getCarId(), SB);
        if (firstMantain != null) {
            //二保计算平均里程
            //本次里程数
            Float thisRunMile = runMile - (Float.valueOf(String.valueOf(firstMantain.get("maintain_mile"))));
            //上次保养时间
            Long beforeMaintainDate = Long.valueOf(String.valueOf(firstMantain.get("maintain_time")));
            //本次平均里程
            Float thisavgMile = this.maintainAvgMile(carMaintain.getMaintainTime(), beforeMaintainDate, thisRunMile);
            avgMile = thisavgMile;
            Float beforeAndThisAvgMile = Float.valueOf(String.valueOf(firstMantain.get("avg_maintain_mile")));
            Float twoAvgMile = (thisavgMile + beforeAndThisAvgMile) / 2;
            //计算车主5000公里需要多少天
            Float dateDifference = DEF_MILE / twoAvgMile;
            Float dateDifferenceHour = dateDifference * 24;
            //设置下一次保养时间
            carMaintain.setNextMaintainTime(DateUtils.addHourLongTime(carMaintain.getMaintainTime(), +dateDifferenceHour.intValue()));
        } else {
            avgMile = this.maintainAvgMile(carMaintain.getMaintainTime(), guaranteeDate, runMile);
        }
        return avgMile;
    }


    /**
     * 保养定保计算 平均里程
     *
     * @param carMaintain   保养信息
     * @param guaranteeDate 质保时间
     * @param runMile       保养里程
     * @return
     * @throws Exception
     */
    private Float maintainDbAvgMile(TCrmCarMaintain carMaintain, long guaranteeDate, Float runMile) throws Exception {
        float avgMile = 0f;
        //1、本次向前取三次（本次保养工单为第四次），并以保养时间为准 倒序
        List<Map<String, Object>> maintainList = crmCarMaintainMileTaskDao.findDbMainTainList(carMaintain.getCompanyId(), carMaintain.getMaintainTime(), carMaintain.getCarId());
        //2、取出最后一次保养
        if (maintainList != null) {

            int maintainListSize = maintainList.size();
            //本次为第最后一次
            //取出第一交次的信息 （当前长度-1 得出最后一次保养信息）
            Map<String, Object> lastMantain = maintainList.get(maintainListSize - 1);
            Float thisRunMile = runMile - (Float.valueOf(String.valueOf(lastMantain.get("maintain_mile"))));
            //上次保养时间
            Long beforeMaintainDate = Long.valueOf(String.valueOf(lastMantain.get("maintain_time")));
            //本次平均里程计算平均日里程
            Float thisavgMile = this.maintainAvgMile(carMaintain.getMaintainTime(), beforeMaintainDate, thisRunMile);
            avgMile = thisavgMile;
            //综合前四次 获得平均里程
            Float dbAvgMile = this.threeMainAvgMile(thisavgMile, maintainList);
            //计算车主5000公里需要多少天
            Float dateDifference = DEF_MILE / dbAvgMile;
            Float dateDifferenceHour = dateDifference * 24;
            //设置下一次保养时间
            System.out.println(carMaintain.getMaintainTime() + "      " + DateUtils.addHourLongTime(carMaintain.getMaintainTime(), +dateDifferenceHour.intValue()));
            carMaintain.setNextMaintainTime(DateUtils.addHourLongTime(carMaintain.getMaintainTime(), +dateDifferenceHour.intValue()));
        } else {

        }
        return avgMile;
    }

    /**
     * 里程 除 时间 得出平均日里程
     *
     * @param maintainTime
     * @param guaranteeDate
     * @param runMile
     * @return
     */
    private Float maintainAvgMile(long maintainTime, long guaranteeDate, Float runMile) throws ParseException {
        Integer difference = DateUtils.dateDifference(maintainTime, guaranteeDate);
        if (difference > 0) {
            return runMile / difference.floatValue();
        }
        return runMile.floatValue();
    }

    /**
     * 根据 里程数/(保养时间 减 质保时间)
     *
     * @param maintainTime 本次保养时间
     * @param firstMantain 上次保养信息
     * @param runMile      本次保养里程数
     * @return
     */
    private Float towMaintainAvgMile(long maintainTime, Map<String, Object> firstMantain, Long runMile, int maintainNums) throws ParseException {
        //首保平均里程
        Long firstMile = Long.valueOf(String.valueOf(firstMantain.get("avg_maintain_mile")));
        //首保保养时间
        Long firstMaintainTime = Long.valueOf(String.valueOf(firstMantain.get("maintain_time")));
        //上次里程数
        Long firstRunMile = Long.valueOf(String.valueOf(firstMantain.get("maintain_mile")));
        //二保 本次保养时间 减 上次保养时间 算出天数
        Integer days = DateUtils.dateDifference(maintainTime, firstMaintainTime);
        //本次里程/天数 本次平均里程
        Float secondMile = (runMile - firstRunMile) / days.floatValue();
        //(本次平均里程+上次里程)/2
        return (firstMile + secondMile) / maintainNums;
    }

    /**
     * 定保计算悉保养里程
     * //     * @param maintainTime 本次保养时间
     * //     * @param lastMantain 上一次保养内容
     * //     * @param runMile 本次保养里程数
     *
     * @param maintainList 所有的保养信息 从本次向前取3条
     * @return
     */
    private Float threeMainAvgMile(Float thisavgMile, List<Map<String, Object>> maintainList) throws ParseException {
//        //上一次保养时间
//        Long lastMaintainTime=Long.valueOf(String.valueOf(lastMantain.get("maintain_time")));
//        //上次里程数
//        Float lastRunMile=Float.valueOf(String.valueOf(lastMantain.get("maintain_mile")));
//        //定保 本次保养时间 减 上次保养时间 算出天数
//        Integer days=DateUtils.dateDifference(maintainTime,lastMaintainTime);
//        //本次里程/天数 本次平均里程
//        Float thisMile=null;
//        if(days!=0){
//            thisMile=(runMile-lastRunMile)/days;
//        }else{
//            thisMile=runMile-lastRunMile;
//        }
        for (Map<String, Object> map : maintainList) {
            //取出第一次的平均保养里程
            Float avgMile = Float.valueOf(String.valueOf(map.get("avg_maintain_mile")));
            thisavgMile += avgMile;
        }
        return thisavgMile / (maintainList.size() + 1);
    }

    /**
     * 获得最后一条保养信息的保养时间
     *
     * @return
     * @throws Exception
     */
    private Long getLastMaintainTime(String type, String companyId) throws Exception {
        Map<String, Object> map = crmCarMaintainMileTaskDao.findLastMainTailMileInfo(type, companyId);
        if (map != null) {
            Long time = Long.valueOf(String.valueOf(map.get("maintain_time")));
            return time;
        }
        return null;
    }


    /**
     * 解析并生成查询sql
     *
     * @param maintainTypeList
     * @return
     */
    private String analyCompanyToSql(List<Map<String, Object>> maintainTypeList, List<Object> params, String companyId, String type) {
//        StringBuffer sqlStr=new StringBuffer();
//        sqlStr.append("SELECT temp1.*, car.guarantee_start_date,car.id AS carId, car.plate_num AS plateNum, car.contact_phone, " +
//                "car.contact_name FROM ( select * from ( SELECT * FROM ( " +
//                "SELECT " +
//                "t.id,t.company_id,t.order_num,t.balance_date,t.type,t2.vin, " +
//                "t.plate_num,t.run_mile, " +
//                "CASE " +
//                "WHEN t.type = '索赔' THEN " +
//                "t.maintain_amount " +
//                "ELSE " +
//                "t.balance_amount " +
//                "END AS amount, " +
//                "CASE " );
//        for (Map<String,Object> item:maintainTypeList) {
//            String pName=String.valueOf(item.get("maint_p_name"));
//            String itemName=String.valueOf(item.get("maint_project_name"));
//            //特殊处理
//            if(pName.equals(DEFTYPE)){
//                continue;
//            }
//            int order=Integer.valueOf(String.valueOf(typeMap.get(pName)));
//            sqlStr.append(String.format(" WHEN LOCATE('%s',t2.item_name) THEN '%s%s' ",itemName,order,pName));
//        }
//        int order=Integer.valueOf(String.valueOf(typeMap.get(DEFTYPE)));
//        sqlStr.append(String.format("ELSE '%s%s' ",order,DEFTYPE));
//        sqlStr.append(" END AS mType,t.create_time " +
//                "FROM t_crm_car_workorder t,t_crm_car_workitem t2 " +
//                "WHERE " +
//                "t.company_id=? ");
//        if(lastTime!=null){
//            sqlStr.append("AND t.balance_date >? ");
//        }
//        sqlStr.append("AND t.order_num = t2.order_code " +
//                "AND t.company_id = t2.company_id " +
//                "AND ( CASE WHEN t.type = '索赔' THEN t.maintain_amount ELSE t.balance_amount END > 0) " +
//                "ORDER BY t.balance_date DESC) worder WHERE worder.mType =? ORDER BY worder.mType ASC " +
//                ") t1 GROUP BY t1.order_num ) " +
//                "temp1 LEFT JOIN t_crm_car car ON temp1.company_id = car.company_id " +
//                "AND temp1.plate_num = car.plate_num limit ?,?");
        StringBuffer sqlStr = new StringBuffer();
        sqlStr.append("SELECT worder.*, car.guarantee_start_date,car.buy_date, car.id AS carId, car.plate_num AS plateNum, car.contact_phone, " +
                "car.contact_name,car.owner_name,car.owner_tel,car.owner_phone  from  t_crm_car_workorder worder, t_crm_car car " +
                "WHERE " +
                "worder.company_id = car.company_id " +
                "AND worder.vin = car.vin " +
                "AND worder.car_id = car.id " +
//                "AND worder.plate_num='鲁A228KX'" +
//                "AND worder.vin='LSVX225N1G2207243' "+
                " ");
        sqlStr.append("AND worder.company_id=? AND worder.wx_type=? and worder.run_mile is not null");
        params.add(companyId);
        params.add(type);
//        if(lastTime!=null){
//            sqlStr.append("AND worder.balance_date >? ");
//        }
        sqlStr.append(" AND not EXISTS(select * from t_crm_car_maintain where worder.id=worder_id and company_id=? and maintian_type=?) ");
        params.add(companyId);
        params.add(type);
        sqlStr.append(" AND EXISTS(select * from t_crm_car car where car.vin=worder.vin and (guarantee_start_date is not null or buy_date is not NULL) and car.company_id=? ) ");
        params.add(companyId);
        sqlStr.append(" AND worder.real_amount>'0.00' and balance_date is not null");
        sqlStr.append(" GROUP BY worder.order_num " +
                "order by worder.balance_date ASC " +
                "limit ?,? " +
                "");
        return sqlStr.toString();
    }

    /**
     * 设置保养类型的排序号
     */
    private void setTypeOrder() {
        typeMap.put("首保", "1");
        typeMap.put("二保", "2");
        typeMap.put("定保", "3");
        typeMap.put("事故车", "4");
        typeMap.put("一般维修", "5");
    }


    /**
     * 更新车辆下次保养时间、保养里程
     *
     * @return
     * @throws Exception
     */
    @Override
    @MethodComment(name = "更新车辆下次保养时间、保养里程")
    public Integer updCarNextMaintainMileAndTmeQuartz() throws Exception {
        Integer limit = 5000;
        Integer nums = 0;
        Integer start = 0;
        while (true) {
            String sql = " update t_crm_car car, ( " +
                    "select car_id,vin,MAX(maintain_time) maintain_time,MAX(maintain_mile*1) maintain_mile,MAX(next_maintain_time) next_maintain_time, " +
                    "MAX(next_maintain_mile*1) next_maintain_mile,company_id from t_crm_car_maintain main group by vin limit ?,?" +
                    ") temp " +
                    "set car.next_maintain_date=temp.next_maintain_time,car.next_maintain_mile=temp.next_maintain_mile where car.vin=temp.vin and car.company_id=temp.company_id";
            int num = this.crmCarMaintainMileTaskDao.executeSQL(sql, start * limit, limit);
            if (num == 0) {
                start = 0;
                break;
            }
            System.out.println(num);
            nums += num;
            start++;
        }
        return nums;
    }

    /**
     * 1、查找不是本店购车，并且vin信息不为空的车辆信息，并且半年以内的车辆信息
     * 2、将其工单信息生成，保养定保工单，存入保养里程表
     * 3、根据基盘信息对应的车辆工单，只有该工单认定为定保，不论类型，并且产值大于0
     * 4、
     *
     * @throws Exception
     */
    @Override
    @MethodComment(name = "社会招揽车辆生成保养任务")
    public Integer carSolicitMaintainTaskQuartz() throws Exception {
        Integer nums = 0;
        Long nowTimeL = DateUtils.addMonthLongTime(DateUtils.getNowTime(), -6);
        String nowTimeStr = DateUtils.getTimeStr(new Date(nowTimeL), "yyyy-MM-dd");
        int start = 0;
        while (true) {
            List<TCrmCarMaintain> crmCarMaintainList = new ArrayList<>();
            String sql = "select detail.*,car.contact_tel,car.owner_name,car.owner_tel from t_crm_car_base_detail detail , t_crm_car car " +
                    " where  detail.vin=car.vin and detail.company_id=car.company_id and detail.tag_date>=? and detail.vin is not null and " +
                    "detail.base_type=3 and not EXISTS(select * from t_crm_car car where detail.vin=car.vin and car.from_company='是') limit ?,?";
            List<Map<String, Object>> list = crmCarMaintainMileTaskDao.list(sql, nowTimeStr, start * LIMIT, LIMIT);
            if (list.size() == 0) {
                start++;
                break;
            }
            //遍历查询基盘信息
            for (Map<String, Object> detailMap : list) {
                //取出车辆信息，查询工单信息，从基盘车辆的标记日期开始查询，第一条工单产值大于0信息列为定保信息
                String carId = String.valueOf(detailMap.get("carId"));
                String vin = String.valueOf(detailMap.get("vin"));
                String plateNum = String.valueOf(detailMap.get("plateNum"));
                String tagDate = String.valueOf(detailMap.get("tagDate"));
                String companyId=String.valueOf(detailMap.get("companyId"));
                Long tagDateL = DateUtils.dayToLongTime(tagDate);
                Map<String, Object> infOMap = this.getWorkorderInfo(companyId,vin, tagDateL);
                if (infOMap != null) {
                    //判断是否有相应的保养工单信息
                    Integer i = crmCarMaintainMileTaskDao.findWorderCounts(String.valueOf(infOMap.get("id")));
                    if (i == 0) {
                        TCrmCarMaintain crmCarMaintain = this.creatMaintainMile(infOMap, detailMap);
                        if (crmCarMaintain != null) {

                            crmCarMaintainList.add(crmCarMaintain);
                        }
                    }
                }
            }
            if (crmCarMaintainList.size() > 0) {
                int num = crmCarMaintainList.size();
                crmCarMaintainMileTaskDao.insertMaintailLists(crmCarMaintainList);
                nums += num;
            }
            start++;
        }
        return nums;
    }

    private TCrmCarMaintain creatMaintainMile(Map<String, Object> map, Map<String, Object> detailMap) throws Exception {
        TCrmCarMaintain maintain = new TCrmCarMaintain();
        maintain.setCompanyId(String.valueOf(map.get("companyId")));//公司ID
        maintain.setCarId(String.valueOf(map.get("carId")));//车辆ID
        maintain.setVin(String.valueOf(map.get("vin")));//车驾号
        maintain.setMaintainTime(Long.valueOf(String.valueOf(map.get("balanceDate"))));//保养时间
        maintain.setMaintainMile(String.valueOf(map.get("runMile")));
        maintain.setMaintainType("定保");//保养类型
        maintain.setWorderId(String.valueOf(map.get("id")));//工单ID
        maintain.setPlateNum(String.valueOf(map.get("plateNum")));
        maintain.setContactName(String.valueOf(map.get("ownerName")));
        if (detailMap.get("ownerTel") != null) {
            maintain.setContactPhone(String.valueOf(detailMap.get("ownerTel")));
        }
        //下次保养时间
        Long nextMaintainTime = DateUtils.addMonthLongTime(maintain.getMaintainTime(), +6);
        maintain.setNextMaintainTime(nextMaintainTime);
        //下次保养里程
        System.out.println(maintain.getVin());
        Float runMile = Float.valueOf(maintain.getMaintainMile());
        maintain.setNextMaintainMile(String.valueOf(runMile + Constant.DEF_MILE));
        maintain.setAvgMaintainMile("0");
        return maintain;
    }

    private Map<String, Object> getWorkorderInfo(String companyId,String vin, Long tagDate) throws Exception {
        StringBuffer sql = new StringBuffer();
        sql.append("select * from ( ");
        sql.append("select workder.company_id,workder.car_id,workder.vin,workder.balance_date,workder.id,car.plate_num," +
                "car.contact_name,car.contact_phone,workder.run_mile from t_crm_car_workorder workder,t_crm_car car where car.vin=workder.vin " +
                "and  workder.vin=? and workder.company_id=? and workder.real_amount>'0.00' and workder.balance_date>=? and workder.run_mile is not null order by workder.balance_date ASC limit 0,1");
        sql.append(") t where t.id not in (select worder_id from t_crm_car_maintain where vin=? and company_id=?)");
        List<Map<String, Object>> listMap = crmCarMaintainMileTaskDao.list(sql.toString(), vin,companyId, tagDate, vin,companyId);
        if (listMap.size() > 0) {
            return listMap.get(0);
        }
        return null;
    }

    /**
     * 1、查找不vin信息不为空的车辆信息，并且半年以内的车辆信息
     * 2、将其工单信息生成，保养定保工单，存入保养里程表
     * 3、根据基盘信息对应的车辆工单，只有该工单认定为定保，不论类型，并且产值大于0
     * 4、删除原有信息之前的保养工单信息
     *
     * @throws Exception
     */
    @Override
    @MethodComment(name = "流失返还车辆生成保养任务")
    public Integer carLossToBackMaintainTaskQuartz() throws Exception {
        Integer nums = 0;
        Long nowTimeL = DateUtils.addMonthLongTime(DateUtils.getNowTime(), -6);
        String nowTimeStr = DateUtils.getTimeStr(new Date(nowTimeL), "yyyy-MM-dd");
        int start = 0;
        while (true) {
            List<String> crmCarMaintainList = new ArrayList<>();
            String sql = "select detail.*,car.contact_tel from t_crm_car_base_detail detail , t_crm_car car " +
                    " where  detail.vin=car.vin and detail.company_id=car.company_id and detail.tag_date>=? and detail.vin is not null and " +
                    "detail.base_type=2  limit ?,?";
            List<Map<String, Object>> list = crmCarMaintainMileTaskDao.list(sql, nowTimeStr, start * LIMIT, LIMIT);
            if (list.size() == 0) {
                start++;
                break;
            }
            //遍历查询基盘信息
            for (Map<String, Object> detailMap : list) {
                //取出车辆信息，查询工单信息，从基盘车辆的标记日期开始查询，第一条工单产值大于0信息列为定保信息
                String carId = String.valueOf(detailMap.get("carId"));
                String vin = String.valueOf(detailMap.get("vin"));
                String plateNum = String.valueOf(detailMap.get("plateNum"));
                String tagDate = String.valueOf(detailMap.get("tagDate"));
                Long tagDateL = DateUtils.dayToLongTime(tagDate);
                String companyId=String.valueOf(detailMap.get("companyId"));
                Map<String, Object> infOMap = this.getWorkorderInfo(companyId,vin, tagDateL);
                if (infOMap != null) {
                    Integer i = crmCarMaintainMileTaskDao.findWorderCounts(String.valueOf(infOMap.get("id")));
                    if (i == 0) {
                        TCrmCarMaintain crmCarMaintain = this.creatMaintainMile(infOMap, detailMap);
                        //删除之前的保养工单信息
                        createMainTosql(crmCarMaintain, crmCarMaintainList);
                    }
                }
            }
            if (crmCarMaintainList.size() > 0) {
                int num = crmCarMaintainList.size();
                crmCarMaintainMileTaskDao.insertAndDelMaintailLists(crmCarMaintainList);
                nums += num;
            }
            start++;
        }
        return nums / 2;
    }

    /**
     * 生成删除及插入sql
     *
     * @param crmCarMaintain
     * @param sqlLists
     */
    private void createMainTosql(TCrmCarMaintain crmCarMaintain, List<String> sqlLists) {
        String deletesql = "delete from t_crm_car_maintain where vin='" + crmCarMaintain.getVin() + "' and company_id='" + crmCarMaintain.getCompanyId() + "'";
        String insertsql = "insert into" +
                "        t_crm_car_maintain" +
                "        (avg_maintain_mile, car_id, company_id, " +
                "contact_name, contact_phone, maintain_mile, maintain_time, maintian_type, next_maintain_time, plate_num, vin, worder_id,next_maintain_mile, id) " +
                "    values" +
                "        ( '" + crmCarMaintain.getAvgMaintainMile() + "', '" + crmCarMaintain.getCarId() + "', '" + crmCarMaintain.getCompanyId() + "'," +
                " '" + crmCarMaintain.getContactName() + "', '" + crmCarMaintain.getContactPhone() + "', '" + crmCarMaintain.getMaintainMile() + "'," +
                " '" + crmCarMaintain.getMaintainTime() + "', '定保', '" + crmCarMaintain.getNextMaintainTime() + "', '" + crmCarMaintain.getPlateNum() + "'," +
                " '" + crmCarMaintain.getVin() + "', '" + crmCarMaintain.getWorderId() + "','" + crmCarMaintain.getNextMaintainMile() + "', replace(UUID(),'-',''))";
        sqlLists.add(deletesql);
        sqlLists.add(insertsql);
    }

    public static void main(String[] args) {
        String mile = "20265.0";
        Float fMile = Float.valueOf(mile);
        System.out.println(fMile.intValue());
    }
}
